#ifndef _LINKED_LINK_H
#define _LINKED_LINK_H
#include "utils.h"
/* Definitions for abstract linked_list. */

typedef struct linked_list_data_t *linked_list_t;

typedef void *linked_list_element_t;

typedef int (*linklist_key_cmp_fn_t)(void* keyA, void* keyB);  // returns 0 if the keys are equal, not-zero otherwise

typedef void (*linked_list_value_destroy_fn_t)(void* value);      // callback to client code to destroy a value, if the hash table
                                                           		  //   isn't empty when it's destroyed
typedef void (*linked_list_key_destroy_fn_t)(void* key);          // callback to destroy a key


#ifndef FALSE
#define FALSE 0
#define TRUE (!FALSE)
#endif // FALSE

/*
 * Creates and returns a new linked_list.
 * Returns null on failure, else a valid linked_list.
 */
extern linked_list_t linked_list_create();

/*
 * Appends an element to the end of the linked_list.
 */
extern int linked_list_update_or_append(linked_list_t l, linked_list_element_t k, linked_list_element_t e);


/*
 * Returns TRUE if linked_list is empty. FALSE otherwise.
 */
extern boolean_t linked_list_is_empty(linked_list_t l);


// well... destroys the hash table
extern int linked_list_destroy( linked_list_t l,
                              linked_list_key_destroy_fn_t   destroyKeyFunc,
                              linked_list_value_destroy_fn_t destroyValFunc
                            );


/*
 *Searh for a given key
 */
extern linked_list_element_t  linked_list_key_search(linked_list_t l, linked_list_element_t k);

typedef void *linked_list_pfapply_closure_t;
typedef boolean_t (linked_list_pfapply_t)(linked_list_element_t,linked_list_element_t, linked_list_pfapply_closure_t);

extern boolean_t linked_list_apply(linked_list_t l, linked_list_pfapply_t pf, linked_list_pfapply_closure_t cl);


#endif //_LINKED_LINK_H


